// 类作用域和对象数组
#include <string>
#include <iostream>
#include "../exercise/44usingClass.hpp"

int main(int argc, char const *argv[])
{
    // 和普通的标准类型数组相同
    UsingClass uc_array[10]; // 创建一个数组长度为10的UsingClass对象数组,并且使用默认的构造函数.(如果没有默认构造函数将会报错)
    // 其中一个对象的调用方式是:
    uc_array[0].show();
    // Company: no name  Shares: 0
    //   Share Price: $0.000  Total Worth: $0.000

    UsingClass using_brace_array[10] = {
        UsingClass("aquawius", 10),
        UsingClass("AQUAWIUS"), // (UsingClass)dynamic-init: <constructor-call>
        UsingClass("NanoSmart", 0, 0.0),
        UsingClass()
        // ...
        // 剩下的元素将会使用默认构造函数进行初始化
    };
    // 对象数组的初始化方案是:  !! 1.先使用默认构造函数进行全部类的实例化,
    //                        !! 2.花括号中的构造函数将会创建临时对象,
    //                        !! 3.将临时对象的内容复制到数组中已经初始化完成的类,并且调用析构函数销毁临时对象
    // 这样类就必须满足[类中必须有默认构造函数],才能使用大括号初始化创建对象数组

    // 类作用域
    // 1.作用域为类的变量
    // 比如,类声明可能使用字面量20作为指定数组的长度,这个变量对于所有对象来说都是相同的,因此创建一个类共享变量是一个不错的主意
    // 但是直接通过类进行初始化是无效的:就像下面这样
    // private:
    //      const int array_size = 30;
    //      double array[array_size];
    // 这样声明是不行的! 因为类本身就是描述类的结构,并没有实际为这个私有的常量分配空间

    // 有两种方法来创建这样的数据成员
    // 1. 使用enum
    // 在类声明中声明的枚举的作用域为整个类,因此可以使用枚举为整形常量提供作用域为整个类的符号名称.
    // private:
    //      enum {array_size = 30};
    //      double array[array_size];
    // 本质上这里的枚举array_size只是一个符号名称,在作用域为整个类的代码中遇到他时,编译器将会用30进行替换

    // 扩展知识: 在很多实现中,ios_base类在公有部分中完成了类似的工作,比如说ios_base::fixed等标识符就来自这里,其中ios_base::fixed就是一个典型的枚举量,定义在ios_base中

    // 2. 使用static关键字
    // private:
    //      static const int array_size = 30;
    //      double array[array_size];
    // 这样创建了一个常量,但是这个常量和其他的静态变量存储在一起,而不是存储在对象中. 因此只有一个静态常量被所有类对象共享

    // 作用域内枚举 (C++11)
    // 在创建类枚举时,有可能会出现这样的情况
    // private:
    //     enum egg_old = {Small,Medium,Larger,Jumbo};
    //     enum egg = {Small,Medium,Larger,Jumbo};
    // 这样两个枚举处于同一个类名称空间,变量名将会冲突
    // C++11 提供了这样的一个枚举,其枚举的作用域为类,声明长这样:
    enum class /*struct*/ egg
    {
        Small,
        Medium,
        Larger,
        Jumbo
    }; // 前面的class或者struct都可以,应该说可以使用struct代替class
    // 使用: 需要使用枚举名称限定枚举变量
    // egg choice = egg::Large;

    return 0;
}

// g++ -Wall -g .\45classScope.cpp ..\exercise\44usingClass.cpp ..\exercise\44usingClass.hpp -o .\45classScope.exe